package com.ljt.springsecuritylogin;

import cn.hutool.jwt.JWT;
import com.ljt.springsecuritylogin.domain.Users;
import com.ljt.springsecuritylogin.enums.Role;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.Date;

@Service
@RequiredArgsConstructor
// TODO 这个类的很多方法，一看上去就是面向过程的编程，如果可以的话，可重构为面向对象的编程
public class JwtService {
    private final JwtConfig jwtConfig;

    public String generateAccessToken(Users user) {
        //5 m
        final int tokenExpiration = Integer.parseInt(jwtConfig.getAccessTokenExpiration());

        return generateToken(user, tokenExpiration);
    }
    public String generateRefreshToken(Users user) {
        //7 day
        final int tokenExpiration = Integer.parseInt(jwtConfig.getRefreshTokenExpiration());

        return generateToken(user, tokenExpiration);
    }

    private String generateToken(Users user, int tokenExpiration) {
        return JWT.create()
                .setSubject(user.getUsername())
                .setIssuedAt(new Date())
                .setExpiresAt(new Date(System.currentTimeMillis() + 1000 * tokenExpiration))
                .setSigner("HS256", jwtConfig.getSecret().getBytes())
                // 我这里建议是存也存字符串，存数字，在hutool上有bug
                .setPayload("userId", user.getId().toString())
                .setPayload("role", user.getRole().toString())
                .sign();
    }

    public boolean validateToken(String token) {
        // 验证签名是否正确，验证时间有没有到期。这个挺强大的，这个leeway点进去源码发现是，容忍令牌过期的时间。
        return JWT.of(token).setKey(jwtConfig.getSecret().getBytes()).validate(0);
    }


    public String getUsername(String token) {
        JWT jwt = JWT.of(token);
        return (String) jwt.getPayload("sub");
    }
    public Long getUserId(String token) {
        JWT jwt = JWT.of(token);
        return Long.valueOf((String) jwt.getPayload("userId"));
    }
    public Role getRole(String token) {
        JWT jwt = JWT.of(token);
        return Role.valueOf((String) jwt.getPayload("role"));
    }
}
